﻿using System.Data;
using RestSharp;

namespace MRMDS_Client
{
    internal class ClientAPIBind : IDisposable
    {
        private string token;
        private string? uuid;
        private RestClient? client;

        public enum ClientType
        {
            Actor,
            Viewer
        }

        public ClientAPIBind(string token)
        {
            this.token = token;
            uuid = null;
            client = null;
        }

        public bool Connect(string root, int port)
        {
            RestClientOptions options = new RestClientOptions($"{root}:{port}");
            client = new RestClient(options);
            var request = new RestRequest("Hello", Method.Get);
            var response = client.Get(request);
            return response.IsSuccessful;
        }

        public bool Login(ClientType type, out string? uuid)
        {
            var request = new RestRequest("Login")
                .AddQueryParameter("token", token)
                .AddQueryParameter("type", type.ToString());
            var response = client!.Post<string>(request);
            uuid = response;
            return response != null;
        }

        public bool Logout()
        {
            var request = new RestRequest("Logout")
                .AddQueryParameter("token", token);
            var response = client!.Delete<DefaultResponse>(request);
            return response != null && response.Success;
        }

        public bool UpdateActorInfo(ActorInfo info)
        {
            var request = new RestRequest("Actor/Info")
                .AddQueryParameter("uuid", uuid)
                .AddJsonBody<ActorInfo>(info);
            var response = client!.Put<DefaultResponse>(request);
            return response != null && response.Success;
        }

        public bool UpdateActorState(ActorState state)
        {
            var request = new RestRequest("Actor/State")
                .AddQueryParameter("uuid", uuid)
                .AddJsonBody<ActorState>(state);
            var response = client!.Put<DefaultResponse>(request);
            return response != null && response.Success;
        }

        public bool CommandActor(Command command)
        {
            var request = new RestRequest("Actor/Command")
                .AddQueryParameter("uuid", uuid)
                .AddJsonBody<Command>(command);
            var response = client!.Post<DefaultResponse>(request);
            return response != null && response.Success;
        }

        public bool PostActorEvent(string eventString)
        {
            var request = new RestRequest("Actor/Event")
                .AddQueryParameter("uuid", uuid)
                .AddBody(eventString);
            var response = client!.Post<DefaultResponse>(request);
            return response != null && response.Success;
        }

        public bool GetActorInfo(out ActorInfo? actorInfo)
        {
            var request = new RestRequest("Actor/Info")
                .AddQueryParameter("uuid", uuid);
            actorInfo = client!.Get<ActorInfo>(request);
            return actorInfo != null;
        }
        public bool GetActorState(out ActorState? actorState)
        {
            var request = new RestRequest("Actor/State")
                .AddQueryParameter("uuid", uuid);
            actorState = client!.Get<ActorState>(request);
            return actorState != null;
        }
        public bool GetActorCommand(out Command? command)
        {
            var request = new RestRequest("Actor/Command")
                .AddQueryParameter("uuid", uuid);
            command = client!.Get<Command>(request);
            return command != null;
        }
        public bool GetActorEvent(out string? eventString)
        {
            var request = new RestRequest("Actor/Event")
                .AddQueryParameter("uuid", uuid);
            eventString = client!.Get<string>(request);
            return eventString != null;
        }

        public bool DelateActorEvent()
        {
            var request = new RestRequest("Actor/Event")
                .AddQueryParameter("uuid", uuid);
            var response = client!.Delete<DefaultResponse>(request);
            return response != null && response.Success;
        }

        public bool GetActorInfos(ActorInfoResponse[]? actorInfos)
        {
            var request = new RestRequest("Actor/Infos");
            actorInfos = client!.Get<ActorInfoResponse[]>(request);
            return actorInfos != null;
        }

        public bool SetViewerWatchSet(string[] uuids)
        {
            var request = new RestRequest("Viewer/WatchSet")
                .AddQueryParameter("uuid", uuid)
                .AddJsonBody<string[]>(uuids);
            var response = client!.Get<DefaultResponse>(request);
            return response != null && response.Success;
        }

        public bool GetViewerWathSetActorStates(out ActorStateResponse[]? actorStates)
        {
            var request = new RestRequest("Viewer/CurrentStates")
                .AddQueryParameter("uuid", uuid);
            actorStates = client!.Get<ActorStateResponse[]>(request);
            return actorStates != null;
        }

        public void Dispose()
        {
            if (client != null)
                ((IDisposable)client).Dispose();
        }
    }
}
